
"""
"""
import unittest as ut
from time import sleep

import basicVdsTest as vdst
import vdsClient as vdsc
from vdsClient import BLANK_UUID
from storageConnectionTestUtils import eStorageType, disconnectFromStorage, connectToStorage, validateConnections, CONNECTIONS_OPTION_DEFAULT
from storageDomainTestUtils import eDomainClass, generateDomainTargets, destroyDomainTargets
from confUtils import Validate
from iptables import blockConnection, unblockConnection
from spmTests import eSpmStatus
from testUtils import retry
from agentUtils import connectAgent

# TODO : clean up test when proper logging is interoduced to RUTH.
#        Move to a proper suite when deciding how to handle such tests

class RecoverFromDeleteImage(vdst.BasicVDSTest):
    #For convenience. I didn't put it in the base class because I didn't want to commit.
    mycfg = property(lambda self: self.cfg[self.__class__.__name__])
    @classmethod
    def getConfigTemplate(cls):
        return {cls.__name__: {
            "VdsUri1" : {"default" : "http://server:54321"},
            "Connections" : {"default" : CONNECTIONS_OPTION_DEFAULT, "validator" : validateConnections},
            "DomainClass1" : {"default" : "data", "validator" : eDomainClass.parse},
            "Domain1" : {"default" : "GUID, GUID", "validator" : Validate.list},
            "StorageType1": {"default" : "nfs", "validator" : eStorageType.parse},
            "HostID1" : {"default" : 7, "validator" : Validate.int},
            "Pool1Key" : {"default" : "NFSKEY"}
            }
        }

    def setUp(self):
        # Setup clients
        print 'setup clients'
        self.client1 = vdsc.VDSClient()
        self.client1.setURI(self.mycfg["VdsUri1"])
        self.agent1 = connectAgent(self.mycfg["VdsUri1"])

        # Make sure env is clean
        print 'env is clean'
        resp = self.assertVdscOK(self.client1.getConnectedStoragePoolsList())
        self.assertTrue(len(resp['poollist']) == 0, "VDSM 1 is connected to a pool. Dirty env. Bailing out.")

        # Handle storage configuration
        connectToStorage(self.client1, self.mycfg["Connections"])
        self.domainTarget1 = generateDomainTargets(self.client1, self.mycfg["Connections"], [self.mycfg["Domain1"]])[0]

        # Create the tmp domain
        print 'create domain'
        self.sdUUID = vdsc.VDSClient.newUUID()
        self.assertVdscOK(
            self.client1.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID,
                "Storage Domain 1", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )

        # Create tmp pool
        print 'create pool'
        self.spUUID = vdsc.VDSClient.newUUID()
        self.assertVdscOK(
            self.client1.createStoragePool(self.spUUID, "Swimming Pool", self.sdUUID, [self.sdUUID], 1)
           )

        self.assertVdscOK(
            self.client1.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
            )

        self.imgUUID = vdsc.VDSClient.newUUID()
        self.volUUID = vdsc.VDSClient.newUUID()

        # Start SPM on host
        print 'start spm'
        taskid = self.assertVdscOK(self.client1.spmStart(self.spUUID, -1, -1, -1, False))['uuid']
        self.assertVdscTaskOK(self.client1, taskid)

        self.assertVdscOK(
            self.client1.activateStorageDomain(self.sdUUID, self.spUUID)
        )

        #Create image
        print 'create image'
        volsize = (1 ** 30)

        taskID = self.assertVdscOK(
            self.client1.createVolume(self.sdUUID, self.spUUID, self.imgUUID, volsize,
            vdsc.COW_FORMAT, vdsc.PREALLOCATED_VOL, "DATA", self.volUUID, "Nietzsche", blocked = False)
        )['uuid']
        self.assertVdscTaskOK(self.client1, taskID)

    def test(self):
        # Delete image
        print 'delete image'
        taskID = self.assertVdscOK(
            self.client1.deleteImage(self.sdUUID, self.spUUID, self.imgUUID, True, False, False)
        )['uuid']

        sleep(1)

        for connection in self.mycfg["Connections"]:
            self.agent1.restartVdsmService()

        # Wait for VDSM to become responsive again
        retry(lambda : self.assertVdscOK(self.client1.list()), 20)

        # Wait for SPM to start
        print 'Reconnect storage'
        connectToStorage(self.client1, self.mycfg["Connections"])
        self.assertVdscOK(
            self.client1.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
            )

        print 'wait for spm to start'
        taskid = self.assertVdscOK(self.client1.spmStart(self.spUUID, self.mycfg["HostID1"], 0, -1, True))['uuid']
        # If SPM takes too long to start this means it does things it shouldn't
        self.assertVdscTaskOK(self.client1, taskid, 30)

        print 'wait for delete task to finish'
        self.assertVdscTaskFail(self.client1, taskID, 9999)
        self.assertEquals(len(self.assertVdscOK(self.client1.getImagesList(self.sdUUID))['imageslist']), 0)

    def tearDown(self):
        # Destroy pool
        print 'Destroying pool'
        self.assertVdscOK(
            self.client1.deactivateStorageDomain(self.sdUUID, self.spUUID, BLANK_UUID, -1)
        )
        self.assertVdscOK(self.client1.destroyStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"]))

        # Format domain
        print 'Formatting domain'
        self.assertVdscOK(self.client1.formatStorageDomain(self.sdUUID))

        # Disconnect
        print 'Disconnecting'
        destroyDomainTargets(self.client1, [self.domainTarget1])
        disconnectFromStorage(self.client1, self.mycfg["Connections"])

def suite():
    tests = {
        RecoverFromDeleteImage : ["test"]
    }

    resSuite = ut.TestSuite()
    for testcase, methods in tests.iteritems():
        resSuite.addTests(map(testcase, methods))

    return resSuite

validateConfig = lambda cfg : vdst.validateSuiteConfig(suite(), cfg)
